home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / mkerr101.zip / MKERR.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-04  |  5KB  |  224 lines

  1. {****************************************************}
  2. { Turbo Pascal 6.0 MkErr Unit Ver 1.01 1991 ManuSoft }
  3. {****************************************************}
  4.  
  5. unit MKERR;                         {This is Public Domain}
  6. { Look for MkErr.doc file for      rbuf is store of these registers.
  7.   explanation of this code          0: es                            
  8.                                     1: bp                            
  9.                                     2: sp                            
  10.                                     3: ss                            
  11.                                     4: [bp  ] 
  12.                                     5: [bp+2]                        
  13.                                     6: [bp+4]                        
  14. }                                    
  15.  
  16. interface
  17.  
  18. {$DEFINE MkEVer101}
  19.  
  20. const
  21.  
  22.   Version : Word = 101;
  23.   NestErr = 16; 
  24.   {Number of nested error_handles available}
  25.   
  26. var 
  27.   oldx    :pointer;
  28.   {Save pointer for ExitProc routine}
  29.  
  30.   active  :word;
  31.   {Active count of nesting level}
  32.  
  33.   nehalt  :Boolean;
  34.   {Not error --> halt
  35.    does the error device assume nonerror activation of
  36.    errordevice is same as halt. Normally program never
  37.    reaches the errh state without error, but if you
  38.    forget the done/errfree clauses from program this
  39.    happens on the end. With this boolean being TRUE
  40.    (default) you can tell errorhandler to just say
  41.    goodbye when occurred without error.}
  42.  
  43.  
  44. procedure init;
  45. {Initialize error device}
  46.  
  47. procedure done;
  48. {Clear error device}
  49.  
  50. function  errset:boolean;
  51. function  errh:boolean;
  52. procedure errfree;
  53. {Errset  setup error device error handler}
  54. {Errh    errorhandler caller. Returns program to position saved by Errset}
  55. {Errfree clears last level of errset information}
  56.  
  57. procedure halt;
  58. {System unit halt procedure override}
  59.  
  60. procedure continue;
  61. {Method to go back and continue program from next statement after error}
  62.  
  63. implementation
  64.  
  65. type
  66.   rbuftype = array[0..6] of word;
  67.   {Type of error device buffer, saves ES,BP,SP,SS,[BP],[BP+2],[BP+4]}
  68.   
  69. var
  70.   rbuf     : array[0..NestErr-1] of rbuftype;
  71.   {Nesting buffer of device error handlers}
  72.  
  73.   bpbuf    : word;
  74.   bpchk    : word;
  75.  
  76. {Device initialization, clear all error handlers.}
  77. procedure init;
  78. begin
  79.   active:=0;
  80.   fillchar(rbuf,sizeof(rbuf),#0);
  81.   oldx:=exitproc;
  82. end;
  83.  
  84. {Device deactivation, clear all error handlers and return exitproc.}
  85. procedure done;
  86. begin
  87.   exitproc:=oldx;
  88.   active:=0;
  89. end;
  90.  
  91. {THE Error Handler itself. Remember to keep this far call proc.
  92.  errh Restores recorded program status from rbuf stack}
  93. {$F+,S-}
  94. function errh:boolean;
  95. begin
  96.   if (erroraddr=nil) and nehalt then halt;
  97.   if active>0 then begin
  98.     asm
  99.       mov  bpbuf,bp;{Save state of bp reg for continue}
  100.       mov  ax,bp
  101.       neg  ax
  102.       mov  bpchk,ax
  103.  
  104.       mov  ax,active;
  105.       dec  ax;
  106.       mov  bx,14; {NOTICE: sizeof(rgbuf);}
  107.       mul  bx;
  108.       lea  si,rbuf;
  109.       add  si,ax
  110.       lodsw
  111.       mov  es,ax
  112.       lodsw
  113.       cli
  114.       mov  bp,ax
  115.       lodsw
  116.       mov  sp,ax
  117.       lodsw
  118.       mov  ss,ax
  119.       sti
  120.       lodsw
  121.       mov  [bp],ax;
  122.       lodsw
  123.       mov  [bp+2],ax
  124.       lodsw
  125.       mov  [bp+4],ax
  126.     end;
  127.     exitproc:=@errh;
  128.   end else halt;
  129.   errh:=true;
  130. end;
  131.  
  132. {Error Handler setup function. Remember to keep this far call prog.
  133.  errset saves its own return value to internal rbuf stack.
  134.  when error occurs, Turbo Pascal ExitProc routine (=Errh) starts
  135.  and restores the saved information from rbuf stack. This makes
  136.  Turbo Pascal to continue code from inside the errset IF clause. }
  137. {$S+}
  138. function errset:boolean;
  139. begin
  140.   if (active=0) and (exitproc<>@errh) then oldx:=exitproc;
  141.   if active<NestErr then begin
  142.     exitproc:=@errh;
  143.     asm
  144.       mov  ax,active;
  145.       mov  bx,14; {NOTICE This is sizeof(rgbuf), won't work in asm}
  146.       mul  bx;
  147.       lea  bx,rbuf
  148.       add  bx,ax
  149.       mov  di,bx
  150.       cld;
  151.       mov  ax,es
  152.       push ds
  153.       pop  es
  154.       stosw
  155.       cli
  156.       mov  ax,bp
  157.       stosw
  158.       mov  ax,sp
  159.       stosw
  160.       mov  ax,ss
  161.       stosw
  162.       sti
  163.       mov  ax,[bp]
  164.       stosw
  165.       mov  ax,[bp+2]
  166.       stosw
  167.       mov  ax,[bp+4]
  168.       stosw
  169.       mov  es,[bx];
  170.     end;
  171.     inc(active);
  172.     errset:=false;
  173.   end else errset:=true;
  174. end;
  175. {$F-}
  176.  
  177. {Free top level error handler, drop to previous level if none}
  178. Procedure errfree;
  179. begin
  180.   if active>0 then dec(active);
  181.   if (active=0) then exitproc:=oldx else exitproc:=@errh;
  182. end;
  183.  
  184. procedure halt;
  185. begin
  186.   Done;
  187.   system.halt;
  188. end;
  189.  
  190. procedure continue; assembler;
  191. asm
  192.   pop   cx
  193.   pop   dx
  194.   mov   ax,word[prefixseg]
  195.   add   ax,word[erroraddr+2]
  196.   add   ax,$10; {Adding program header size ($100 bytes) to segment address}
  197.   push  ax
  198.   mov   bx,word[erroraddr]
  199.   push  bx
  200.   or    ax,bx
  201.   jnz   @@1
  202.   mov   al,nehalt;
  203.   or    al,al
  204.   jz    @@2
  205.   call  halt;  {No continue address & nehalt true, halt}
  206. @@2:
  207.   push  dx     {No continue address & nehalt false, return to caller}
  208.   push  cx
  209. @@1:
  210.   mov  ax,bpchk;
  211.   neg  ax
  212.   cmp  ax,bpbuf;
  213.   jnz  @@3
  214.   mov  bpchk,ax
  215.   mov  bp,ax
  216. @@3:
  217. end;
  218.  
  219. begin
  220.   nehalt:=True;
  221.   init; {Clear the device on startup}
  222. end.
  223.  
  224.